package service.thread;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.mail.Message;
import javax.mail.MessagingException;

import service.EmailUtil;
import service.ThreadUtil;


public class SenderThreadPool {
	
	private int threadCount = Runtime.getRuntime().availableProcessors();
	private List<Message> listMessages;
	private Set<String> setSender;	
	private List<Thread> listThread;
	
	public SenderThreadPool(List<Message> listMessages) {
		this.listMessages = listMessages;
		this.setSender = new HashSet<>();
		this.listThread = new ArrayList<>(threadCount);
	}
	
	public Set<String> execute() {
		
		List<List<Message>> list = this.splitList();
		
		for (List<Message> listMessages : list) {
			this.listThread.add(new SenderMessageThread(listMessages, this.setSender));
		}
		
		ThreadUtil.startThreads(this.listThread);
		
		return this.setSender;
	}
	
	private List<List<Message>> splitList() {

		int[] arrayMaxIndex = this.generateIndexs(this.listMessages);
		List<List<Message>> list = new ArrayList<>(this.threadCount);
		int end = 0;
		int start = 0;

		for (int i = 0; i < this.threadCount; i++) {
			end += (arrayMaxIndex[i]);
			list.add(listMessages.subList(start, end));
			start += arrayMaxIndex[i];
		}

		return list;
	}

	private int[] generateIndexs(List<Message> listMessages) {

		int value = listMessages.size() / this.threadCount;
		
		int[] arrayMaxIndex = new int[this.threadCount];

		for (int i = 0; i < this.threadCount; i++) {
			arrayMaxIndex[i] = value;
		}
		arrayMaxIndex[this.threadCount - 1] += listMessages.size() % threadCount;

		return arrayMaxIndex;
	}
	
}

class SenderMessageThread extends Thread {

	private List<Message> listMessages;
	private Set<String> setSender;
	
	public SenderMessageThread(List<Message> listMessages, Set<String> setSender) {
		this.listMessages = listMessages;
		this.setSender = setSender;
	}
	
	@Override
	public void run() {

		try {
			this.getSenderMessages();
		} catch (MessagingException | IOException e) {
			e.printStackTrace();
		}
	}
	
	private void getSenderMessages() throws MessagingException, IOException {

		for (Message message : this.listMessages) {
			this.setSender.add(EmailUtil.getSender(message));
		}
	}
}